package security.Authentication.Encrypted;

import java.security.GeneralSecurityException;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import security.Authentication.Base.AuthenticationRequest;
import security.Authentication.Base.User;
import security.Authentication.UserPass.UserPassHandler;
import security.Authentication.UserPass.UserPassRequest;

/**
 * An authentication handler that accepts a user with encrypted
 * user name and password
 * @author Andreas Carmvall
 */
public class EncryptedHandler extends UserPassHandler {

	@Override
	public User handleRequest(AuthenticationRequest request) {
		if (request instanceof EncryptedRequest) {
			EncryptedRequest encryptedRequest = (EncryptedRequest)request;
			String decryptedUserName;
			String decryptedPassword;

			// Decrypt the user information
			try {
				decryptedUserName = decryptText(encryptedRequest.getEncryptedUserName());
				decryptedPassword = decryptText(encryptedRequest.getEncryptedPassword());
			} catch (GeneralSecurityException e) {
				decryptedUserName = null;
				decryptedPassword = null;
			}

			// Check the user information
			UserPassRequest userPassRequest = 
					new UserPassRequest(
							request.getAddress(),
							decryptedUserName,
							decryptedPassword);
			
			return super.handleRequest(userPassRequest);
		} else {
			return passRequestToNext(request);
		}
	}

	/**
	 * Decrypt an AES encrypted text
	 * @param text the bytes to be decrypted
	 * @return the decrypted text
	 * @throws GeneralSecurityException if the decryption failed
	 */
	private String decryptText(byte[] text) throws GeneralSecurityException {
		final String passphrase = "This is the passphrase."; // Use a fixed passphrase
		Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
		MessageDigest digest = MessageDigest.getInstance("SHA");
		
		digest.update(passphrase.getBytes());
		SecretKeySpec key = new SecretKeySpec(digest.digest(), 0, 16, "AES");
		aes.init(Cipher.DECRYPT_MODE, key);
		
		byte[] cleartext = aes.doFinal(text);
		
		return new String(cleartext);
	}
}
